const fs = require('fs');

// 生成完整的OPUS文件头
function generateOpusHeader(sampleRate = 16000, channels = 1, preSkip = 0) {
    const header = new ArrayBuffer(25);  // 25字节，与app.js匹配
    const view = new DataView(header);
    const uint8Array = new Uint8Array(header);

    // "OpusHead" 标识 (8字节)
    const opusHead = "OpusHead";
    for (let i = 0; i < 8; i++) {
        uint8Array[i] = opusHead.charCodeAt(i);
    }

    // 版本号 (1字节)
    uint8Array[8] = 1;

    // 通道数 (1字节)
    uint8Array[9] = channels;

    // 预跳过样本数 (2字节, 小端序)
    view.setUint16(10, preSkip, true);

    // 采样率 (4字节, 小端序)
    view.setUint32(12, sampleRate, true);

    // 输出增益 (2字节, 小端序)
    view.setUint16(16, 0, true);

    // 通道映射 (1字节)
    uint8Array[18] = 0;

    // 自定义扩展信息 (6字节)
    // 帧大小 (2字节, 小端序)
    view.setUint16(19, 960, true);  // 帧大小
    // 总帧数 (4字节, 小端序) - 这个会在createOpusFileWithFrames中设置
    view.setUint32(21, 0, true);    // 先设为0，后面会更新

    return uint8Array;
}

// 创建包含指定帧数的完整OPUS文件
function createOpusFileWithFrames(opusFrames, outputPath) {
    try {
        // 生成OPUS文件头
        const header = generateOpusHeader();

        // 在文件头中设置正确的总帧数
        const headerView = new DataView(header.buffer);
        headerView.setUint32(21, opusFrames.length, true);  // 在偏移21处设置总帧数（4字节）

        // 计算总大小：头部 + 所有帧数据
        const totalSize = header.length + opusFrames.reduce((total, frame) => total + 4 + frame.length, 0);

        // 创建ArrayBuffer
        const buffer = new ArrayBuffer(totalSize);
        const uint8Array = new Uint8Array(buffer);
        const view = new DataView(buffer);

        let offset = 0;

        // 写入文件头
        uint8Array.set(header, offset);
        offset += header.length;

        // 写入所有帧数据
        for (const frame of opusFrames) {
            // 写入帧长度
            view.setUint32(offset, frame.length, true);
            offset += 4;

            // 写入帧数据
            uint8Array.set(frame, offset);
            offset += frame.length;
        }

        // 保存到文件
        fs.writeFileSync(outputPath, uint8Array);

        console.log(`成功创建OPUS文件: ${outputPath}`);
        console.log(`包含 ${opusFrames.length} 帧，文件大小: ${totalSize} 字节`);

        return outputPath;

    } catch (error) {
        console.error('创建OPUS文件失败:', error);
        throw error;
    }
}

module.exports = {
    generateOpusHeader,
    createOpusFileWithFrames
}